using System;
using System.Globalization;
using GammaJul.ReSharper.GammaXaml.Highlightings.CSharp;
using GammaJul.ReSharper.GammaXaml.Psi.Xaml;
using JetBrains.Annotations;
using JetBrains.Application.Progress;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Feature.Services.LinqTools;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.Xaml.Impl.Resolve;
using JetBrains.TextControl;
using JetBrains.Util;

namespace GammaJul.ReSharper.GammaXaml.QuickFixes.CSharp {

	/// <summary>
	/// Quick fix that changes a dependency property registered name.
	/// </summary>
	[QuickFix]
	public sealed class ChangeDpNameFix : QuickFixBase {
		private readonly MismatchedDpNameHighlighting _highlighting;
		private readonly string _dpName;

		public override string Text {
			get {
				return String.Format(
					CultureInfo.CurrentCulture,
					"Change registered name of '{0}' to '{1}'",
					_highlighting.DpField.ShortName,
					_dpName);
			}
		}
		
		protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) {
			IPsiModule psiModule = _highlighting.NameArgument.PsiModule;

			_highlighting.NameArgument.Expression.ReplaceBy(CSharpElementFactory
				.GetInstance(psiModule)
				.CreateExpressionByConstantValue(new ConstantValue(_dpName, psiModule)));

			return null;
		}

		public override bool IsAvailable(IUserDataHolder cache) {
			if (!_highlighting.IsValid() || String.IsNullOrEmpty(_dpName))
				return false;

			IConstantValueOwner constantValueOwner = _highlighting.NameArgument.Expression;
			return constantValueOwner != null
				&& constantValueOwner.ConstantValue.IsString()
				&& !String.Equals(_dpName, (string) constantValueOwner.ConstantValue.Value, StringComparison.Ordinal);
		}

		public ChangeDpNameFix([NotNull] MismatchedDpNameHighlighting highlighting) {
			if (highlighting == null)
				throw new ArgumentNullException("highlighting");
			_highlighting = highlighting;
			_dpName = highlighting.DpField.GetExpectedDpName(XamlTypeCache.GetCache(highlighting.DpField.Module));
		}
	}

}
